package com.lingyun.mqttserver;

import com.lingyun.mqttserver.dao.mapper.DeviceInfoMapper;
import com.lingyun.mqttserver.dao.mapper.MqttScreenVariableMappingMapper;
import com.lingyun.mqttserver.dao.mapper.MqttScreenVariableMappingVariableMapper;
import com.lingyun.mqttserver.dao.pojo.DeviceInfo;
import com.lingyun.mqttserver.dao.pojo.MqttScreenVariableMapping;
import com.lingyun.mqttserver.service.impl.MqttMessageService;
import com.lingyun.mqttserver.util.JSONUtil;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.*;
import java.util.stream.Collectors;

@SpringBootTest
public class MqttSchel {

    @Autowired
    private MqttScreenVariableMappingMapper mqttScreenVariableMappingMapper;

    @Autowired
    private MqttScreenVariableMappingVariableMapper mqttScreenVariableMappingVariableMapper;

    @Autowired
    private DeviceInfoMapper deviceInfoMapper;

    @Autowired
    private MqttMessageService mqttMessageService;

    @Autowired
    private JdbcTemplate jdbcTemplate;



    @Test
    public void pushMQTT() {
        // 1. 获取所有屏幕ID
        List<MqttScreenVariableMapping> mappings = mqttScreenVariableMappingMapper.selectList(null);
        Set<Integer> screenIds = mappings.stream()
                .map(MqttScreenVariableMapping::getScreenId)
                .collect(Collectors.toSet());

        if (screenIds.isEmpty()) return;

        // 2. 单次查询所有数据
        List<Map<String, Object>> allData = selectBatchVariablesWithValues(new ArrayList<>(screenIds));

        // 3. 按屏幕分组处理
        Map<Integer, Map<String, Object>> screenData = allData.stream()
                .collect(Collectors.groupingBy(
                        data -> (Integer) data.get("screen_id"),
                        Collectors.toMap(
                                data -> (String) data.get("mqtt_variable_name"),
                                data -> data.get("current_value")
                        )
                ));

        // 4. 批量获取设备信息
        List<DeviceInfo> devices = deviceInfoMapper.selectBatchIds(new ArrayList<>(screenIds));
        Map<Integer, String> addressMap = devices.stream()
                .collect(Collectors.toMap(DeviceInfo::getId, DeviceInfo::getHardwareAddress));

        // 5. 发送MQTT
        for (Map.Entry<Integer, Map<String, Object>> entry : screenData.entrySet()) {
            Integer screenId = entry.getKey();
            Map<String, Object> variables = entry.getValue();
            String address = addressMap.get(screenId);

            if (address != null && !variables.isEmpty()) {
                mqttMessageService.sendMessage(address + "/subcribe",
                        JSONUtil.toJSON(variables), true);
            }
        }
    }


    private List<Map<String, Object>> selectBatchVariablesWithValues(List<Integer> screenIds) {
        if (screenIds.isEmpty()) {
            return new ArrayList<>();
        }

        String inClause = screenIds.stream()
                .map(String::valueOf)
                .collect(Collectors.joining(","));

        String sql = String.format("""
            SELECT 
                m.screen_id,
                m.mapping_id, 
                m.lower_computer_id,
                m.mqtt_variable_name,
                v.current_value
            FROM mqtt_screen_variable_mapping_variable m
            INNER JOIN lower_computer_variable v ON m.lower_variable_id = v.id
            WHERE m.screen_id IN (%s)
            ORDER BY m.screen_id, m.mapping_id
            """, inClause);

        return jdbcTemplate.queryForList(sql);
    }
}
